package com.tabnet.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;

import com.tabnet.beans.personnes.Adresse;
import com.tabnet.beans.personnes.Fournisseur;
import com.tabnet.dao.DAOAdresse;
import com.tabnet.dao.DAOException;
import com.tabnet.dao.DAOFactory;
import com.tabnet.dao.DAOFournisseur;
import com.tabnet.dao.DAOUtilitaire;

public class FournisseurDAOImpl implements DAOFournisseur {
	private static final String SQL_SELECT        		= "SELECT IDFournisseur, RaisonSociale, MailF, MDP, AdresseID FROM Fournisseur ORDER BY RaisonSociale";
	private static final String SQL_INSERT_FOURNISSEUR 	= "INSERT INTO Fournisseur (IDFournisseur, RaisonSociale, MailF, MDP, AdresseID) VALUES (?, ?, ?, MD5(?), ?);";
	private static final String SQL_MAIL 				= "SELECT IDFournisseur FROM Fournisseur WHERE MailF = ?";
	private static final String SQL_ID 					= "SELECT IDFournisseur FROM Fournisseur WHERE IDFournisseur = ?";
	private static final String SQL_FOURNISSEUR			= "SELECT IDFournisseur, RaisonSociale, MailF, mdp, AdresseID FROM Fournisseur WHERE IDFournisseur = ?";
	private static final String SQL_MDP					= "SELECT IDFournisseur FROM Fournisseur WHERE MailF = ? AND MDP = MD5(?)";
	private static final String SQL_MODIF_FOURNISSEUR	= "UPDATE Fournisseur SET RaisonSociale = ?, MailF = ?,  MDP = MD5(?) WHERE IDFournisseur = ?";
	private static final String SQL_MODIF_SANS_MDP		= "UPDATE Fournisseur SET RaisonSociale = ?, MailF = ? WHERE IDFournisseur = ?";
	
    private DAOFactory daoFactory;
    private static DAOAdresse daoAdresse;

    public FournisseurDAOImpl( DAOFactory daoFactory ) {
        this.daoFactory = daoFactory;
        daoAdresse = daoFactory.getAdresseDAO();
    }

    /* Implémentation de la méthode définie dans l'interface ClientDao */
    @Override
    public HashMap<String, Fournisseur> lister() throws DAOException {
    	Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        HashMap<String, Fournisseur> fournisseurs = new HashMap<String, Fournisseur>();
        Fournisseur fourn;

        try {
            connection = daoFactory.getConnection();
            // récupération des fournissseurs
            preparedStatement = connection.prepareStatement( SQL_SELECT );
            resultSet = preparedStatement.executeQuery();
            while ( resultSet.next() ) {
            	fourn = map( resultSet );
            	fournisseurs.put(fourn.get_IdF(), fourn);
            }
        } catch ( SQLException e ) {
            throw new DAOException( e );
        } finally {
            DAOUtilitaire.fermeturesSilencieuses( resultSet, preparedStatement, connection );
        }

        return fournisseurs;
    }

    /*
     * Simple méthode utilitaire permettant de faire la correspondance (le
     * mapping) entre une ligne issue de la table des fournisseurs (un ResultSet) et
     * un bean Fournisseur.
     */
    private static Fournisseur map( ResultSet resultSet ) throws SQLException {
    	Fournisseur fourn = new Fournisseur();
    	
    	fourn.set_IdF( resultSet.getString( "IDFournisseur" ) );
    	fourn.set_RaisonSociale( resultSet.getString( "RaisonSociale" ) );
    	
		try {
			fourn.set_AdresseF(daoAdresse.trouverAdr(resultSet.getInt( "AdresseID" )));
		} catch (DAOException e) {
			e.printStackTrace();
		}
    	
    	fourn.set_Mail( resultSet.getString( "MailF" ) );
        fourn.set_Mdp( resultSet.getString( "MDP" ) );
        return fourn;
    }

    @Override
	public void addFournisseur(Fournisseur poFournisseur) throws DAOException {
		Connection connexion = null;
        PreparedStatement preparedStatementF = null;
        ResultSet valeursAutoGenerees = null;
        
        try {
            connexion = daoFactory.getConnection();
            Adresse adr = poFournisseur.get_AdresseF();
            daoAdresse.addAdresse(adr);
            
            //insertion fournisseur
	        preparedStatementF = DAOUtilitaire.initialisationRequetePreparee( connexion, SQL_INSERT_FOURNISSEUR, true,
	        		poFournisseur.get_IdF(), poFournisseur.get_RaisonSociale(), poFournisseur.get_Mail(), 
	        		poFournisseur.get_Mdp(), adr.getId() );
            int statut = preparedStatementF.executeUpdate();
            if ( statut == 0 ) {
                throw new DAOException( "Échec de la création du fournisseur, aucune ligne ajoutée dans la table." );
            }
        } catch ( SQLException e ) {
            throw new DAOException( e );
        } finally {
        	 DAOUtilitaire.fermeturesSilencieuses( valeursAutoGenerees, preparedStatementF, connexion );
        }
	}

	@Override
	public void updFournisseur(Fournisseur poFournisseur, String mdp) throws DAOException {
		Connection connexion = null;
        PreparedStatement preparedStatementF = null;
        ResultSet valeursAutoGenerees = null;

        try {
            connexion = daoFactory.getConnection();
            Adresse adr = poFournisseur.get_AdresseF();
            daoAdresse.updAdresse(adr); // modification de l'adresse
            
            // modification fournisseur
            if(mdp != null){
		        preparedStatementF = DAOUtilitaire.initialisationRequetePreparee( connexion, SQL_MODIF_FOURNISSEUR, true,
		        		poFournisseur.get_RaisonSociale(), poFournisseur.get_Mail(), mdp, poFournisseur.get_IdF() );
            }
            else {
		        preparedStatementF = DAOUtilitaire.initialisationRequetePreparee( connexion, SQL_MODIF_SANS_MDP, true,
		        		poFournisseur.get_RaisonSociale(), poFournisseur.get_Mail(), poFournisseur.get_IdF() );
            }
            
            int statut = preparedStatementF.executeUpdate();
            if ( statut == 0 ) {
                throw new DAOException( "Échec de la modification du fournisseur, aucune ligne modifiée dans la table." );
            }
        } catch ( SQLException e ) {
            throw new DAOException( e );
        } finally {
        	 DAOUtilitaire.fermeturesSilencieuses( valeursAutoGenerees, preparedStatementF, connexion );
        }
	}

	@Override
	public boolean verificationMail(String mail, String idF) throws DAOException {
		Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connexion = daoFactory.getConnection();

            preparedStatement = DAOUtilitaire.initialisationRequetePreparee( connexion, SQL_MAIL, true, mail);

            resultSet = preparedStatement.executeQuery();
            /* Parcours de la ligne de données retournée dans le ResultSet */
            resultSet.getRow();
            if ( resultSet.next() ) {
            	// si l'adresse mail correspond à ce client c'est ok
            	if(resultSet.getString("IDFournisseur").equals(idF)){
            		return true;
            	}
            	// sinon l'adresse appartient à un autre fournisseur
            	return false;
            }
            return true;
        } catch ( SQLException e ) {
            throw new DAOException( e );
        } finally {
        	 DAOUtilitaire.fermeturesSilencieuses( resultSet, preparedStatement, connexion );
        }
	}

	@Override
	public boolean verificationID(String id) throws DAOException {
		Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connexion = daoFactory.getConnection();
            preparedStatement = DAOUtilitaire.initialisationRequetePreparee( connexion, SQL_ID, true, id);
            resultSet = preparedStatement.executeQuery();
            /* Parcours de la ligne de données retournée dans le ResultSet */
            if ( resultSet.next() ) {
            	return false;
            }
            return true;
        } catch ( SQLException e ) {
            throw new DAOException( e );
        } finally {
        	 DAOUtilitaire.fermeturesSilencieuses( resultSet, preparedStatement, connexion );
        }
	}

	@Override
	public String verificationMdp(String mail, String mdp) throws DAOException {
		Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        String idF = "0";

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            /*
             * Préparation de la requête avec les objets passés en arguments
             * (ici, uniquement un id) et exécution.
             */
            preparedStatement =  DAOUtilitaire.initialisationRequetePreparee( connexion, SQL_MDP, false, mail, mdp );
            resultSet = preparedStatement.executeQuery();
            /* Parcours de la ligne de données retournée dans le ResultSet */
            if ( resultSet.next() ) {
            	idF = resultSet.getString("IDFournisseur");
            }
        } catch ( SQLException e ) {
            throw new DAOException( e );
        } finally {
            DAOUtilitaire.fermeturesSilencieuses( resultSet, preparedStatement, connexion );
        }

        return idF;
	}

	@Override
	public Fournisseur trouverFourn(String id) throws DAOException {
		if(id == "0"){
			return null;
		}
		else {
			Connection connexion = null;
	        PreparedStatement preparedStatement = null;
	        ResultSet resultSet = null;
	        Fournisseur fourn = new Fournisseur();

	        try {
	            /* Récupération d'une connexion depuis la Factory */
	            connexion = daoFactory.getConnection();
	            /*
	             * Préparation de la requête avec les objets passés en arguments
	             * (ici, uniquement un id) et exécution.
	             */
	            preparedStatement =  DAOUtilitaire.initialisationRequetePreparee( connexion, SQL_FOURNISSEUR, false, id );
	            resultSet = preparedStatement.executeQuery();
	            /* Parcours de la ligne de données retournée dans le ResultSet */
	            if ( resultSet.next() ) {
	            	fourn.set_IdF(resultSet.getString("IDFournisseur"));
	            	fourn.set_AdresseF(daoAdresse.trouverAdr(resultSet.getInt("AdresseID")));
	            	fourn.set_RaisonSociale(resultSet.getString("RaisonSociale"));
	            	fourn.set_Mail(resultSet.getString("MailF"));
	            	fourn.set_Mdp(resultSet.getString("MDP"));
	            }
	        } catch ( SQLException e ) {
	            throw new DAOException( e );
	        } finally {
	            DAOUtilitaire.fermeturesSilencieuses( resultSet, preparedStatement, connexion );
	        }

	        return fourn;
		}
	}
}
